#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
将使用频度数据合并到完整的ABI分析结果中

功能：
在OPENBMC_ABI_ANALYSIS_SUMMARY.xlsx的基础上，增加使用频度列
"""

import json
import sys
from pathlib import Path
from collections import Counter

try:
    import pandas as pd
    import openpyxl
    from openpyxl.styles import Font, PatternFill, Alignment
    HAS_EXCEL = True
except ImportError:
    HAS_EXCEL = False


def main():
    """主函数"""
    project_root = Path(__file__).parent.parent.parent
    
    # 读取完整的ABI分析结果
    abi_summary = project_root / 'output' / 'OPENBMC_ABI_ANALYSIS_SUMMARY.xlsx'
    print(f"[INFO] 读取ABI分析结果: {abi_summary}")
    
    if not abi_summary.exists():
        print(f"[ERROR] ABI分析结果不存在: {abi_summary}")
        return 1
    
    # 读取场景A使用频度（合并后）
    usage_a = project_root / 'output' / 'usage_scenario_a_merged.xlsx'
    print(f"[INFO] 读取场景A使用频度: {usage_a}")
    
    if not usage_a.exists():
        print(f"[ERROR] 场景A使用频度不存在: {usage_a}")
        return 1
    
    # 读取场景B使用频度
    usage_b = project_root / 'output' / 'usage_scenario_b.xlsx'
    print(f"[INFO] 读取场景B使用频度: {usage_b}")
    
    if not usage_b.exists():
        print(f"[WARN] 场景B使用频度不存在，将仅包含场景A数据")
        usage_b = None
    
    # 读取数据
    df_abi = pd.read_excel(abi_summary, sheet_name='完整ABI清单')
    print(f"[INFO] ABI清单: {len(df_abi)} 个函数")
    
    df_usage_a = pd.read_excel(usage_a, sheet_name='按使用频度')
    print(f"[INFO] 场景A使用: {len(df_usage_a[df_usage_a['使用次数'] > 0])} 个函数被使用")
    
    if usage_b:
        df_usage_b = pd.read_excel(usage_b, sheet_name='按使用频度')
        print(f"[INFO] 场景B使用: {len(df_usage_b[df_usage_b['使用次数'] > 0])} 个函数被使用")
    else:
        df_usage_b = None
    
    # 创建使用频度字典
    usage_dict_a = {}
    for _, row in df_usage_a.iterrows():
        func_name = row['函数名']
        usage_dict_a[func_name] = {
            '场景A使用次数': row['使用次数'],
            '场景A仓库数': row['使用仓库数']
        }
    
    usage_dict_b = {}
    if df_usage_b is not None:
        for _, row in df_usage_b.iterrows():
            func_name = row['函数名']
            usage_dict_b[func_name] = {
                '场景B使用次数': row['使用次数'],
                '场景B仓库数': row['使用仓库数']
            }
    
    # 合并到ABI清单（按方法名匹配）
    df_abi['场景A使用次数'] = df_abi['方法'].map(
        lambda x: usage_dict_a.get(x, {}).get('场景A使用次数', 0)
    )
    df_abi['场景A仓库数'] = df_abi['方法'].map(
        lambda x: usage_dict_a.get(x, {}).get('场景A仓库数', 0)
    )
    
    df_abi['场景B使用次数'] = df_abi['方法'].map(
        lambda x: usage_dict_b.get(x, {}).get('场景B使用次数', 0)
    )
    df_abi['场景B仓库数'] = df_abi['方法'].map(
        lambda x: usage_dict_b.get(x, {}).get('场景B仓库数', 0)
    )
    
    # 计算总使用次数
    df_abi['总使用次数'] = df_abi['场景A使用次数'] + df_abi['场景B使用次数']
    
    # 重新排列列顺序：基本信息 + 使用频度 + 原有属性
    columns_order = [
        '库', '命名空间', '类', '方法', '完整签名',
        # 使用频度（新增）
        '场景A使用次数', '场景A仓库数',
        '场景B使用次数', '场景B仓库数',
        '总使用次数',
        # 原有属性
        '有状态', '状态评分',
        '协议类型', '功能域', '调用模式',
        '复杂度', '风险级别', '线程安全'
    ]
    
    df_final = df_abi[columns_order]
    
    # 保存结果
    output_file = project_root / 'output' / 'OPENBMC_ABI_WITH_USAGE.xlsx'
    
    with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
        # Sheet 1: 完整ABI清单（按总使用次数排序）
        df_sorted = df_final.sort_values(['总使用次数', '库', '命名空间', '类', '方法'], ascending=[False, True, True, True, True])
        df_sorted.to_excel(writer, sheet_name='完整ABI清单', index=False)
        
        # Sheet 2: 场景A高频函数（使用次数>0）
        df_used_a = df_final[df_final['场景A使用次数'] > 0].sort_values('场景A使用次数', ascending=False)
        df_used_a.to_excel(writer, sheet_name='场景A使用函数', index=False)
        
        # Sheet 3: 场景B高频函数（使用次数>0）
        df_used_b = df_final[df_final['场景B使用次数'] > 0].sort_values('场景B使用次数', ascending=False)
        df_used_b.to_excel(writer, sheet_name='场景B使用函数', index=False)
        
        # Sheet 4: 两个场景都使用的函数
        df_both = df_final[(df_final['场景A使用次数'] > 0) & (df_final['场景B使用次数'] > 0)].sort_values('总使用次数', ascending=False)
        df_both.to_excel(writer, sheet_name='两场景共用函数', index=False)
        
        # Sheet 5: 未被使用的函数
        df_unused = df_final[df_final['总使用次数'] == 0].sort_values(['库', '命名空间', '类', '方法'])
        df_unused.to_excel(writer, sheet_name='未使用函数', index=False)
        
        # Sheet 6: 按库统计
        lib_stats = []
        for lib in df_final['库'].unique():
            lib_df = df_final[df_final['库'] == lib]
            lib_stats.append({
                '库': lib,
                '总函数数': len(lib_df),
                '场景A使用函数数': len(lib_df[lib_df['场景A使用次数'] > 0]),
                '场景A总调用次数': lib_df['场景A使用次数'].sum(),
                '场景B使用函数数': len(lib_df[lib_df['场景B使用次数'] > 0]),
                '场景B总调用次数': lib_df['场景B使用次数'].sum(),
                '总调用次数': lib_df['总使用次数'].sum(),
                '使用率': f"{len(lib_df[lib_df['总使用次数'] > 0])/len(lib_df)*100:.1f}%"
            })
        df_lib_stats = pd.DataFrame(lib_stats).sort_values('总调用次数', ascending=False)
        df_lib_stats.to_excel(writer, sheet_name='按库统计', index=False)
        
        # Sheet 7: 综合统计
        stats_data = {
            '统计项': [
                '总函数数',
                '场景A使用函数数',
                '场景A总调用次数',
                '场景A使用率',
                '场景B使用函数数',
                '场景B总调用次数',
                '场景B使用率',
                '至少一个场景使用',
                '两个场景都使用',
                '总调用次数'
            ],
            '数值': [
                len(df_final),
                len(df_final[df_final['场景A使用次数'] > 0]),
                df_final['场景A使用次数'].sum(),
                f"{len(df_final[df_final['场景A使用次数'] > 0])/len(df_final)*100:.1f}%",
                len(df_final[df_final['场景B使用次数'] > 0]),
                df_final['场景B使用次数'].sum(),
                f"{len(df_final[df_final['场景B使用次数'] > 0])/len(df_final)*100:.1f}%",
                len(df_final[df_final['总使用次数'] > 0]),
                len(df_final[(df_final['场景A使用次数'] > 0) & (df_final['场景B使用次数'] > 0)]),
                df_final['总使用次数'].sum()
            ]
        }
        df_stats = pd.DataFrame(stats_data)
        df_stats.to_excel(writer, sheet_name='综合统计', index=False)
    
    # 美化Excel
    _format_excel(output_file)
    
    print(f"[SUCCESS] 合并报告已生成: {output_file}")
    
    # 打印统计
    print("\n" + "=" * 80)
    print("使用频度统计")
    print("=" * 80)
    print(f"总函数数: {len(df_final)}")
    print(f"\n【场景A - OpenBMC官方phosphor-*项目】")
    print(f"  使用函数: {len(df_final[df_final['场景A使用次数'] > 0])} ({len(df_final[df_final['场景A使用次数'] > 0])/len(df_final)*100:.1f}%)")
    print(f"  总调用次数: {df_final['场景A使用次数'].sum()}")
    
    print(f"\n【场景B - 厂商OpenBMC fork】")
    print(f"  使用函数: {len(df_final[df_final['场景B使用次数'] > 0])} ({len(df_final[df_final['场景B使用次数'] > 0])/len(df_final)*100:.1f}%)")
    print(f"  总调用次数: {df_final['场景B使用次数'].sum()}")
    
    print(f"\n【综合】")
    print(f"  至少一个场景使用: {len(df_final[df_final['总使用次数'] > 0])} ({len(df_final[df_final['总使用次数'] > 0])/len(df_final)*100:.1f}%)")
    print(f"  两个场景都使用: {len(df_final[(df_final['场景A使用次数'] > 0) & (df_final['场景B使用次数'] > 0)])}")
    print(f"  总调用次数: {df_final['总使用次数'].sum()}")
    
    print(f"\nTop 10 高频函数 (综合):")
    top10 = df_final.nlargest(10, '总使用次数')
    for idx, row in top10.iterrows():
        print(f"  {row['方法']}: {row['总使用次数']}次 (A:{row['场景A使用次数']}, B:{row['场景B使用次数']}) - {row['库']}")
    
    print(f"\nTop 10 高频库 (综合):")
    for idx, row in df_lib_stats.head(10).iterrows():
        print(f"  {row['库']}: {row['总调用次数']}次 (A:{row['场景A总调用次数']}, B:{row['场景B总调用次数']})")
    
    print("=" * 80)
    
    return 0


def _format_excel(excel_path: Path):
    """美化Excel表格"""
    wb = openpyxl.load_workbook(excel_path)
    
    header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
    header_font = Font(bold=True, color="FFFFFF")
    
    for sheet in wb.worksheets:
        # 设置表头样式
        if sheet.max_row > 0:
            for cell in sheet[1]:
                cell.fill = header_fill
                cell.font = header_font
                cell.alignment = Alignment(horizontal='center', vertical='center')
        
        # 自动调整列宽
        for column in sheet.columns:
            max_length = 0
            column_letter = column[0].column_letter
            for cell in column:
                try:
                    if cell.value:
                        max_length = max(max_length, len(str(cell.value)))
                except:
                    pass
            adjusted_width = min(max_length + 2, 80)
            sheet.column_dimensions[column_letter].width = adjusted_width
    
    wb.save(excel_path)


if __name__ == '__main__':
    try:
        sys.exit(main())
    except Exception as e:
        print(f"[ERROR] 合并失败: {e}", file=sys.stderr)
        import traceback
        traceback.print_exc()
        sys.exit(1)

